
Namespace CommonDialog

    ''' <summary>
    '''     Displays a modal custom dialog box and returns the result to the caller.
    ''' </summary>
    Public Class CustomDialog

        'usage
        'Dim x As New CommonDialog.CustomDialog(Nothing, Nothing)
        '    x.InstructionIcon = CommonDialog.CustomDialogIcon.Shield
        '    x.FooterIcon = CommonDialog.CustomDialogIcon.Information
        '    x.Buttons = CommonDialog.CustomDialogButton.OKCancel
        '    x.DefaultButton = CommonDialog.CustomDialogResult.OK
        '    x.Caption = "Dialog Caption"
        '    x.InstructionHeading = "This Is The Heading"
        '    x.InstructionText = "This is the text"
        '    x.FooterText = "This is the footer text"
        '    x.AdditionalDetailsText = "This is some text that can be used to explain the reason for this dialog box."
        'Dim obj As CommonDialog.CustomDialogResult = x.Show()
        ''MessageBox.Show(obj.ToString)
        '
#Region " Private Declarations "

        Private _enumButtons As CustomDialogButton = CustomDialogButton.OK
        Private _enumCustomDialogResult As CustomDialogResult = CustomDialogResult.None
        Private _enumDefaultButton As CustomDialogResult = CustomDialogResult.None
        Private _enumFooterIcon As CustomDialogIcon = CustomDialogIcon.None
        Private _enumInstructionIcon As CustomDialogIcon = CustomDialogIcon.None
        Private _intButtonsDisabledDelay As Integer = 0
        Private _strAdditionalDetailsText As String = String.Empty
        Private _strCaption As String = String.Empty
        Private _strFooterText As String = String.Empty
        Private _strInstructionHeading As String = String.Empty
        Private _strInstructionText As String = String.Empty

#End Region

#Region " Public Properties "

        ''' <summary>
        ''' Gets or sets the optional text is displayed to the user when they click to Show Details expander.  Used to provide a detailed explaination to the user.
        ''' </summary>
        Public Property AdditionalDetailsText() As String
            Get
                Return _strAdditionalDetailsText
            End Get
            Set(ByVal Value As String)
                _strAdditionalDetailsText = Value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the buttons that will be displayed.  The default is the OK button.
        ''' </summary>
        Public Property Buttons() As CustomDialogButton
            Get
                Return _enumButtons
            End Get
            Set(ByVal Value As CustomDialogButton)
                _enumButtons = Value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the number of seconds that the buttons will be disabled, providing time for the user to read the dialog before dismissing it.  Assigning a value also causes a progress bar to display the elapsed time before the buttons are enabled.
        ''' </summary>
        Public Property ButtonsDisabledDelay() As Integer
            Get
                Return _intButtonsDisabledDelay
            End Get
            Set(ByVal Value As Integer)
                _intButtonsDisabledDelay = Value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the dialog box window caption.  The caption is displayed in the window chrome.
        ''' </summary>
        Public Property Caption() As String
            Get
                Return _strCaption
            End Get
            Set(ByVal Value As String)
                _strCaption = Value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the default button for the dialog box.  This value defaults to none.
        ''' </summary>
        Public Property DefaultButton() As CustomDialogResult
            Get
                Return _enumDefaultButton
            End Get
            Set(ByVal Value As CustomDialogResult)
                _enumDefaultButton = Value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the icon displayed in the dialog footer.  This values defaults to none.
        ''' </summary>
        Public Property FooterIcon() As CustomDialogIcon
            Get
                Return _enumFooterIcon
            End Get
            Set(ByVal Value As CustomDialogIcon)
                _enumFooterIcon = Value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the optional text displayed in the footer.
        ''' </summary>
        Public Property FooterText() As String
            Get
                Return _strFooterText
            End Get
            Set(ByVal Value As String)
                _strFooterText = Value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the heading text displayed in the dialog box.
        ''' </summary>
        Public Property InstructionHeading() As String
            Get
                Return _strInstructionHeading
            End Get
            Set(ByVal Value As String)
                _strInstructionHeading = Value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the icon displayed to the left of the instruction text.  This value defaults to none.
        ''' </summary>
        Public Property InstructionIcon() As CustomDialogIcon
            Get
                Return _enumInstructionIcon
            End Get
            Set(ByVal Value As CustomDialogIcon)
                _enumInstructionIcon = Value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the text message for the dialog.
        ''' </summary>
        Public Property InstructionText() As String
            Get
                Return _strInstructionText
            End Get
            Set(ByVal Value As String)
                _strInstructionText = Value
            End Set
        End Property

#End Region

#Region " Constructors "

        Public Sub New()
        End Sub

        Public Sub New(ByVal strCaption As String, ByVal strInstructionHeading As String, ByVal strInstructionText As String, ByVal enumButtons As CustomDialogButton, ByVal enumDefaultButton As CustomDialogResult, ByVal enumInstructionIcon As CustomDialogIcon, Optional ByVal intButtonsDisabledDelay As Integer = 0)
            _strCaption = strCaption
            _strInstructionHeading = strInstructionHeading
            _strInstructionText = strInstructionText
            _enumButtons = enumButtons
            _enumDefaultButton = enumDefaultButton
            _enumInstructionIcon = enumInstructionIcon
            _intButtonsDisabledDelay = intButtonsDisabledDelay
        End Sub

        Public Sub New(ByVal strCaption As String, ByVal strInstructionHeading As String, ByVal strInstructionText As String, ByVal strFooterText As String, ByVal enumButtons As CustomDialogButton, ByVal enumDefaultButton As CustomDialogResult, ByVal enumInstructionIcon As CustomDialogIcon, ByVal enumFooterIcon As CustomDialogIcon, Optional ByVal intButtonsDisabledDelay As Integer = 0)
            _strCaption = strCaption
            _strInstructionHeading = strInstructionHeading
            _strInstructionText = strInstructionText
            _strFooterText = strFooterText
            _enumButtons = enumButtons
            _enumDefaultButton = enumDefaultButton
            _enumInstructionIcon = enumInstructionIcon
            _enumFooterIcon = enumFooterIcon
            _intButtonsDisabledDelay = intButtonsDisabledDelay
        End Sub

        Public Sub New(ByVal strCaption As String, ByVal strInstructionHeading As String, ByVal strInstructionText As String, ByVal strAdditionalDetailsText As String, ByVal strFooterText As String, ByVal enumButtons As CustomDialogButton, ByVal enumDefaultButton As CustomDialogResult, ByVal enumInstructionIcon As CustomDialogIcon, ByVal enumFooterIcon As CustomDialogIcon, Optional ByVal intButtonsDisabledDelay As Integer = 0)
            _strCaption = strCaption
            _strInstructionHeading = strInstructionHeading
            _strInstructionText = strInstructionText
            _strAdditionalDetailsText = strAdditionalDetailsText
            _strFooterText = strFooterText
            _enumButtons = enumButtons
            _enumDefaultButton = enumDefaultButton
            _enumInstructionIcon = enumInstructionIcon
            _enumFooterIcon = enumFooterIcon
            _intButtonsDisabledDelay = intButtonsDisabledDelay
        End Sub

#End Region

#Region " Methods "

        ''' <summary>
        '''     Shows the custom dialog described by the constructor and properties set by the caller, returns CustomDialogResult.
        ''' </summary>
        ''' <returns>
        '''     A CommonDialog.CustomDialogResult value.
        ''' </returns>
        Public Function Show() As CustomDialogResult

            Dim obj As New CustomDialogWindow(Me.ButtonsDisabledDelay)
            obj.tbCaption.Text = Me.Caption

            If Me.FooterText.Length > 0 Then
                obj.tbFooterText.Text = Me.FooterText

                If Me.FooterIcon <> CustomDialogIcon.None Then
                    obj.imgFooterIcon.Source = New BitmapImage(GetIcon(Me.FooterIcon))

                Else
                    obj.imgFooterIcon.Visibility = Visibility.Collapsed
                End If

            Else
                obj.tbFooterText.Visibility = Visibility.Collapsed
                obj.imgFooterIcon.Visibility = Visibility.Collapsed
            End If

            If Me.InstructionIcon = CustomDialogIcon.None Then
                obj.imgInstructionIcon.Visibility = Visibility.Collapsed

            Else
                obj.imgInstructionIcon.Source = New BitmapImage(GetIcon(Me.InstructionIcon))
            End If

            obj.tbInstructionText.Text = Me.InstructionText
            obj.tbInstructionHeading.Text = Me.InstructionHeading

            If Me.AdditionalDetailsText.Length > 0 Then
                obj.tbAdditionalDetailsText.Text = Me.AdditionalDetailsText

            Else
                obj.expAdditionalDetails.Visibility = Visibility.Collapsed
            End If

            SetButtons(obj)
            obj.ShowInTaskbar = False
            obj.Topmost = True
            obj.ShowDialog()
            _enumCustomDialogResult = obj.CustomDialogResult
            LogDialog()
            Return _enumCustomDialogResult
        End Function

        Private Function GetIcon(ByVal enumCustomDialogIcon As CustomDialogIcon) As Uri

            Select Case enumCustomDialogIcon

                Case CustomDialogIcon.Information
                    Return New Uri("CustomDialogInformation.png", UriKind.Relative)

                Case CustomDialogIcon.None
                    Return Nothing

                Case CustomDialogIcon.Question
                    Return New Uri("CustomDialogQuestion.png", UriKind.Relative)

                Case CustomDialogIcon.Shield
                    Return New Uri("CustomDialogShield.png", UriKind.Relative)

                Case CustomDialogIcon.Stop
                    Return New Uri("CustomDialogStop.png", UriKind.Relative)

                Case CustomDialogIcon.Warning
                    Return New Uri("CustomDialogWarning.png", UriKind.Relative)

                Case Else
                    Throw New ArgumentOutOfRangeException("enumCustomDialogIcon", enumCustomDialogIcon.ToString, "Programmer did not program for this icon.")
            End Select

            Return Nothing
        End Function

        Private Sub LogDialog()
            'TODO write common dialog entry to database, event log 
            'don't forget to write the calling properties to the db.
            'don't forget to log the Windows user name to the database
        End Sub

        Private Sub SetButtons(ByVal obj As CustomDialogWindow)

            Select Case Me.Buttons

                Case CustomDialogButton.OK
                    obj.btnCancel.Visibility = Visibility.Collapsed
                    obj.btnNo.Visibility = Visibility.Collapsed
                    obj.btnYes.Visibility = Visibility.Collapsed

                Case CustomDialogButton.OKCancel
                    obj.btnNo.Visibility = Visibility.Collapsed
                    obj.btnYes.Visibility = Visibility.Collapsed

                Case CustomDialogButton.YesNo
                    obj.btnOK.Visibility = Visibility.Collapsed
                    obj.btnCancel.Visibility = Visibility.Collapsed

                Case CustomDialogButton.YesNoCancel
                    obj.btnOK.Visibility = Visibility.Collapsed

                Case Else
                    Throw New ArgumentOutOfRangeException("Buttons", Me.Buttons.ToString, "Programmer did not program for this selection.")
            End Select

            Select Case Me.DefaultButton

                Case CustomDialogResult.Cancel
                    obj.btnCancel.IsDefault = True

                Case CustomDialogResult.No
                    obj.btnNo.IsDefault = True
                    obj.btnCancel.IsCancel = True

                Case CustomDialogResult.None
                    'do nothing
                    obj.btnCancel.IsCancel = True

                Case CustomDialogResult.OK
                    obj.btnOK.IsDefault = True
                    obj.btnCancel.IsCancel = True

                Case CustomDialogResult.Yes
                    obj.btnYes.IsDefault = True
                    obj.btnCancel.IsCancel = True

                Case Else
                    Throw New ArgumentOutOfRangeException("DefaultButton", Me.DefaultButton.ToString, "Programmer did not program for this selection.")
            End Select

        End Sub

#End Region

    End Class

End Namespace
